package net.wicp.tams.common.os;

import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.lang3.Validate;

import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import lombok.extern.slf4j.Slf4j;
import net.wicp.tams.common.Conf;
import net.wicp.tams.common.Result;
import net.wicp.tams.common.apiext.IOUtil;
import net.wicp.tams.common.exception.ExceptAll;
import net.wicp.tams.common.exception.ProjectException;
import net.wicp.tams.common.os.constant.CommandCentOs;
import net.wicp.tams.common.os.pool.SSHConnection;

/***
 * SSH操作类
 * 
 * @author 偏锋书生
 *
 *         2018年7月13日
 */
@Slf4j
public abstract class SSHAssit {

	/****
	 * 获取连接并校验
	 * 
	 * @param ip
	 * @param port
	 * @param username
	 * @param password
	 * @return
	 * @throws ProjectException
	 */
	public static SSHConnection getConn(String ip, int port, String username, String password,int timeout) throws ProjectException {
		Validate.notNull(ip, "SSH connection ip not null");
		Validate.notNull(port, "SSH connection port not null");
		Validate.notNull(username, "SSH connection username not null");
		Validate.notNull(password, "SSH connection password not null");
		Connection conn = new Connection(ip, port);
		try {
			conn.connect(null, Conf.getInt("common.os.ssh.timeout"), timeout);
		} catch (IOException e) {
			String errmsg = "SSH connection timeout with [ ip: " + ip + ", port: " + port + "]";
			log.error(errmsg, e);
			throw new ProjectException(ExceptAll.project_timeout, errmsg);
		}
		try {
			boolean isAuthenticated = conn.authenticateWithPassword(username, password);
			if (isAuthenticated == false) {
				throw new ProjectException(ExceptAll.ssh_auth_fail,
						"SSH authentication failed with [ userName: " + username + ", password: " + password + "]");
			}
		} catch (IOException e) {
			throw new ProjectException(ExceptAll.ssh_auth_fail,
					"SSH authentication failed with [ userName: " + username + ", password: " + password + "]");
		}
		return new SSHConnection(conn);
	}
	
	
	
	public static SSHConnection getConn(String ip, int port, String username, String password) throws ProjectException {
		return getConn(ip,port,username,password,Conf.getInt("common.os.ssh.timeout"));
	}
	

	public static Result callCommand(SSHConnection conn, CommandCentOs command, String grep, Object... params)
			throws Exception {
		Session openSession = conn.getConn().openSession();
		String cmd = command.getCommand(grep, params);
		openSession.execCommand(cmd);
		String slurp = IOUtil.slurp(openSession.getStdout());
		// 获取标准输出
		if (slurp != null) {
			Result suc = Result.getSuc();
			suc.setMessage(slurp);
			return suc;
		}
		// 返回为null代表可能有异常，需要检测标准错误输出，以便记录日志
		Result errResult = tryLogError(openSession.getStderr(), conn.getConn().getHostname(), cmd);
		return errResult;
	}

	private static Result tryLogError(InputStream is, String address, String cmd) throws IOException {
		String errInfo = IOUtil.slurp(is);
		if (errInfo != null) {
			log.error("address " + address + " execute cmd:({}), err:{}", cmd, errInfo);
			return Result.getError(errInfo);
		}
		return Result.getError("unknow");
	}

}
